﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Arch.Data;
using Arch.Intercep.Interceptors;
using Microsoft.Practices.Unity;

namespace Arch.Intercep
{
    public class DefaultInterceptorManager : IInterceptorManager
    {
        [Dependency]
        public IDictionary<IInterceptor, ActionTarget> Interceptors { get; set;}

        public virtual void Intercept<T>(IRepository<T> repository, ActionTarget target) where T : class, new()
        {
            foreach (var interceptor in Interceptors.Where(i => i.Key is IRepositoryInterceptor &&i.Value.HasFlag(target)))
            {
                ((IRepositoryInterceptor)interceptor.Key).Intercept(repository, target);
            }
        }

        public virtual object Intercept(object entity, ActionTarget target)
        {
            foreach (var interceptor in Interceptors.Where(i => i.Key is IEntityInterceptor && i.Value.HasFlag(target)))
            {
                ((IEntityInterceptor)interceptor.Key).Intercept(entity, target);
            }
            return entity;
        }

        public virtual IEnumerable<T> Loaded<T>(IEnumerable<T> result) where T : class, new()
        {
            foreach (var interceptor in Interceptors.Where(i => i.Key is IEntityInterceptor && i.Value.HasFlag(ActionTarget.Loaded)))
            {
                foreach (var entity in result)
                {
                    ((IEntityInterceptor)interceptor.Key).Intercept(entity, ActionTarget.Loaded);
                }
            }
            return result;
        }

        #region Intercept methods
        public virtual void InfrastructureLoading<T>(IRepository<T> repository) where T : class, new()
        {
            Intercept(repository, ActionTarget.InfrastructureLoading);
        }

        public virtual void InfrastructureLoaded<T>(IRepository<T> repository) where T : class, new()
        {
            Intercept(repository, ActionTarget.InfrastructureLoaded);
        }
        #endregion
    }
}
